package com.example.game_dafangdaxie.View;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.example.game_dafangdaxie.R;
import com.example.game_dafangdaxie.StringConstant.Point;
import com.example.game_dafangdaxie.StringConstant.TouchList;
import com.example.game_dafangdaxie.StringConstant.TouchXY;
import com.example.game_dafangdaxie.StringConstant.WINSTATUS;
import com.example.game_dafangdaxie.algorithm.ConditionalJudgment;
import com.example.game_dafangdaxie.algorithm.JudgmentWin;
import com.example.game_dafangdaxie.algorithm.ProAI;
import com.example.game_dafangdaxie.algorithm.changePiece;
import com.example.game_dafangdaxie.resUtils.mSoundPool;

import java.util.ArrayList;

@SuppressLint("ViewConstructor")
public class AiView extends SurfaceView implements SurfaceHolder.Callback,Runnable, View.OnTouchListener {
    //是否亮屏
    private boolean isDraw;
    //行
    private final static int ROW = 6;
    private final static int COL = 6;
    //屏幕宽
    private static float WIDTH;
    private static float HEIGHT;
    private Drawable background;
    private SurfaceHolder surfaceHolder;
    //棋盘长度
    private static float length;
    //棋盘最上面离顶部距离
    private static float DistanceTop;
    //棋盘里左侧距离
    private static final float DistanceLeft = 50f;
    //棋盘间隔
    private static float Spacing;
    private final Context context;
    //总棋盘数组
    private static ArrayList<TouchXY> touchXYList;
    private static Point CurrentPoint;
    //红方玩家
    private static int play = 0;
    //步数
    private static int steps = 1;
    private static Point startPoint;
    //奖励步数
    private static int RewardSteps = 0;
    private com.example.game_dafangdaxie.resUtils.mSoundPool mSoundPool;
    private Drawable  btn_red_fail;
    private float red_fail_minX, red_fail_maxX, red_fail_minY, red_fail_maxY;
    private static boolean isStartRePaint=false;//是否需要重画
    private static boolean isEnd=false;
    /***
     * ValidClickAreaLength 有效点击长度
     */
    private static float minX, minY, maxX, maxY, ValidClickAreaLength;
    /***有效xy坐标
     * XList
     * YList
     */
    private static ArrayList<Float> XList = new ArrayList<>();
    private static ArrayList<Float> YList = new ArrayList<>();
    private Boolean isMove=false;

    public Handler handler=new Handler(Looper.myLooper()){
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case 0x00:
                    isComputerWin();
                    break;
                case 0x01:
                    isEnd=true;
                    touchXYList.clear();
                    break;
                case 0x02:
                    isEnd=false;
                    break;
            }
        }
    };
    public AiView(Context context, Boolean isDraw) {
        super(context);
        this.isDraw = isDraw;
        this.setFocusable(true);
        this.context = context;
        this.setFocusableInTouchMode(true);
        mSoundPool=new mSoundPool(context);
        background = getResources().getDrawable(R.drawable.single, null);
        btn_red_fail = getResources().getDrawable(R.drawable.red_fail, null);
        surfaceHolder = getHolder();
        surfaceHolder.addCallback(this);
        setOnTouchListener(this);
        setFocusable(true);
        setKeepScreenOn(true);
        setFocusableInTouchMode(true);
        touchXYList = new ArrayList<>();
        initGame();
    }

    private void initGame() {
        touchXYList.clear();
        RewardSteps = 0;
        isStartRePaint=false;
        play = 0;
        handler.sendEmptyMessage(0x02);
        isMove = false;
        steps = 1;
    }

    @SuppressLint("Range")
    private void redraw() {
        Canvas mCanvas = surfaceHolder.lockCanvas();
        if(mCanvas!=null){
            if (steps > 3) {
                steps = 3;
            }
            background.setBounds(0, 0, (int) WIDTH, (int) HEIGHT);
            background.draw(mCanvas);
            btn_red_fail.setBounds((int) red_fail_minX, (int) red_fail_minY,
                    (int) red_fail_maxX, (int) red_fail_maxY);
            btn_red_fail.draw(mCanvas);
            Paint paint = new Paint();
            paint.setColor(Color.BLACK);
            paint.setStrokeWidth(3);
            for (int i = 0; i < ROW; i++) {
                for (int j = 0; j < COL; j++) {
                    //横线
                    mCanvas.drawLine(DistanceLeft, j * Spacing + DistanceTop, length + DistanceLeft, j * Spacing + DistanceTop, paint);
                    //竖线
                    mCanvas.drawLine(i * Spacing + DistanceLeft, DistanceTop, i * Spacing + DistanceLeft, DistanceTop + length, paint);
                    Paint paint1 = new Paint();
                    paint1.setTextSize(55f);
                    if (play == 0) {
                        paint1.setARGB(240,188,43,63);
                        mCanvas.drawText("红方" + steps + "步", DistanceLeft + Spacing * 3 / 2, DistanceTop + length + Spacing, paint1);
                        mCanvas.drawCircle(DistanceLeft + Spacing, DistanceTop + length + Spacing, 50, paint1);
                        if (RewardSteps != 0) {
                            mCanvas.drawText("红方奖励" + RewardSteps + "步", DistanceLeft + Spacing * 3 / 2, DistanceTop + length + Spacing * 3 / 2, paint1);
                        }
                    }
                }
            }
            Paint paint1=new Paint();
            paint1.setStrokeWidth(6);
            paint1.setColor(Color.WHITE);
            AiGo();
            if (touchXYList.size() > 0) {
                for (int i=0;i<touchXYList.size();i++){
                    if(i==touchXYList.size()-1){
                        drawPiece.draw(mCanvas, startPoint, Spacing, touchXYList.get(i), 1);
                    }else{
                        drawPiece.draw(mCanvas, startPoint, Spacing, touchXYList.get(i), -1);
                    }
                }//for
            }
            surfaceHolder.unlockCanvasAndPost(mCanvas);
        }
    }

    public void isComputerWin() {
        int WINCODE = JudgmentWin.JudgmentWin(touchXYList);
        String[] winMessage = {"平局", "红方胜", "蓝方胜"};
        if (WINCODE > WINSTATUS.NO_END) {
            handler.sendEmptyMessage(0x01);
            AlertDialog.Builder dialog = new AlertDialog.Builder(context);
            dialog.setTitle("游戏结束");
            dialog.setMessage(winMessage[WINCODE]);
            dialog.setCancelable(false);
            dialog.setNegativeButton("再玩一次", (dialog1, which) -> {
                initGame();
                new Thread(this::redraw).start();
                dialog1.dismiss();
            });
            dialog.show();
        }
    }

        private void AiGo(){
        while (play==1&&isMove){
            ProAI proAI=new ProAI(touchXYList);
            Point aiPoint=proAI.getAllPoint();
            if(aiPoint!=null){
                isStartRePaint=true;
                touchXYList.add(new TouchXY(aiPoint,play));
                int bCounts=0;
                for (TouchXY txy:touchXYList){
                    if(txy.play==1){
                        bCounts++;
                    }
                }

               if(bCounts==19){
                   handler.sendEmptyMessage(0x00);
                   isMove=false;
                   break;
               }else if(touchXYList.size()==36){
                   handler.sendEmptyMessage(0x00);
                   isMove=false;
                   break;
                }
                steps--;
                ConditionalJudgment cj=new ConditionalJudgment(aiPoint,touchXYList,play,0);
                if(cj.getSteps()>0){
                    steps+=cj.getSteps();
                }
                play=changePiece.getChange(steps,play);
                if(play==0){
                    steps=1;
                    isMove=false;
                    isStartRePaint=false;
                }
            }else {
                isMove=false;
                isStartRePaint=false;
            }

        }
        if(isStartRePaint){
            new Thread(this::redraw).start();
        }

    }

    @Override
    public void surfaceCreated(@NonNull SurfaceHolder holder) {
        new Thread(this::redraw).start();
    }

    @Override
    public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
        HEIGHT = height;
        WIDTH = width;
        length = width - DistanceLeft * 2;
        DistanceTop = (HEIGHT - length) / 2;
        Spacing = length / 5;
        ValidClickAreaLength = 4*Spacing / 9;
        minX = DistanceLeft - ValidClickAreaLength;
        minY = DistanceTop - ValidClickAreaLength;
        maxX = DistanceLeft + length + ValidClickAreaLength;
        maxY = DistanceTop + length + ValidClickAreaLength;
        red_fail_minX = (WIDTH - 2 * Spacing) / 2;
        red_fail_minY = (HEIGHT - Spacing * 3 / 2);
        red_fail_maxX = (((WIDTH - 2 * Spacing) / 2) + 2 * Spacing);
        red_fail_maxY = HEIGHT - Spacing * 3 / 2 + 150;
        for (int i = 0; i < COL; i++) {
            XList.add(i* Spacing + DistanceLeft);
        }
        for (int j = 0; j < ROW; j++) {
            YList.add(j* Spacing + DistanceTop);
        }
        startPoint = new Point(DistanceLeft, DistanceTop);
    }

    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
        isDraw = false;
        mSoundPool.Close();

    }


    @Override
    public void run() {
        if (isDraw&&!isEnd) {
            redraw();
        }
    }
    private Point getFormat(float x,float y) {
        float tempX = -1;
        float tempY = -1;
        if(x> minX&&x<maxX &&y>minY &&y<maxY) {
            for (float X : XList) {
                if (x >= X - ValidClickAreaLength && x < X + ValidClickAreaLength) {
                    tempX = X;
                }
            }
            for (float Y : YList) {
                if (y >= Y - ValidClickAreaLength && y < Y + ValidClickAreaLength) {
                    tempY = Y;
                }
            }
        }
        return new Point(tempX,tempY);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        float x=event.getX();
        float y=event.getY();
        if(event.getAction()==MotionEvent.ACTION_DOWN){
            mSoundPool.start(0);
            return true;
        }
        if(play==0) {
            if (event.getAction() == MotionEvent.ACTION_UP) {
                if(x> minX&&x<maxX &&y>minY &&y<maxY){
                    Point tempPoint = getFormat(x, y);
                    if (tempPoint.x != -1f && tempPoint.y != -1f) {
                        CurrentPoint = new Point((tempPoint.x-startPoint.x)/Spacing,(tempPoint.y-startPoint.y)/Spacing);
                        TouchXY touchXY = new TouchXY(CurrentPoint, play);
                        if (!TouchList.Contains(touchXYList, CurrentPoint)) {
                            touchXYList.add(touchXY);
                            steps--;
                            //初始化奖励步数
                            RewardSteps=0;
                            //判断是否符合加步数条件
                            ConditionalJudgment cj=new ConditionalJudgment(CurrentPoint,touchXYList,play,0);
                            if(cj.getSteps()>0){
                                steps+=cj.getSteps();
                                mSoundPool.start(1);
                            }
                            RewardSteps=cj.getSteps();
                            play=changePiece.getChange(steps,play);
                            if(play==1){
                                steps=1;
                                isMove=true;
                            }
                            new Thread(this).start();
                        }else {
                            Toast.makeText(context,"此处已经有棋子了",Toast.LENGTH_SHORT).show();
                        }
                    }else {
                        Toast.makeText(context, "棋子要下在交点上", Toast.LENGTH_SHORT).show();
                    }
                }else {
                    if(x>=red_fail_minX&&x<=red_fail_maxX && y>=red_fail_minY && y<=red_fail_maxY){
                        mDialog mDialog=new mDialog(context,WINSTATUS.BLUE_WIN);
                        mDialog.DialogShow();
                        initGame();
                        new Thread(this).start();
                    }else {
                        Toast.makeText(context,"请点击棋盘内",Toast.LENGTH_SHORT).show();
                    }
                }
                isComputerWin();
            }

        }

        return true;
    }

}
